#include "CWebsocketTool.h"
#include "ui_CWebsocketTool.h"

CWebsocketTool::CWebsocketTool(QWidget *parent)
    : QWidget(parent)
    , ui(new Ui::CWebsocketTool)
{
    ui->setupUi(this);
    m_pWebSocketSrever = new QWebSocketServer("WebSocketServer", QWebSocketServer::NonSecureMode, this);
    ui->btnOpenServer->setEnabled(true);
    ui->btnCloseServer->setEnabled(false);
    m_WebSocketList.clear();

    m_pWebSocketClient = new QWebSocket(QString("WebSocketClient"));
    connect(m_pWebSocketClient, SIGNAL(error(QAbstractSocket::SocketError)), this, SLOT(SlotClientConnectError(QAbstractSocket::SocketError)));
    connect(m_pWebSocketClient, &QWebSocket::connected, this, &CWebsocketTool::SlotClientConnected);
    connect(m_pWebSocketClient, &QWebSocket::disconnected, this, &CWebsocketTool::SlotClientDisconnected);
    connect(m_pWebSocketClient, &QWebSocket::textMessageReceived, this, &CWebsocketTool::SlotClientReceiveMessages, Qt::QueuedConnection);
    ui->btnClientConnect->setEnabled(true);
    ui->btnClientDisconnect->setEnabled(false);
    ui->labClientStatus->setStyleSheet("color:red;");
    ui->labClientStatus->setText("Disconnect");
}

CWebsocketTool::~CWebsocketTool()
{
    delete ui;
}

void CWebsocketTool::ClientOutputMessage(QString strMessage, EM_MESSAGE_SHOW_COLOR emShowColor)
{
    switch ( emShowColor )
    {
        case EM_MESSAGE_SHOW_COLOR_RED:
        {
            ui->tdtClientReceiveMessage->setTextColor("red");
            ui->tdtClientReceiveMessage->append("系统消息：" + strMessage);
        }
            break;
        case EM_MESSAGE_SHOW_COLOR_BLUE:
        {
            ui->tdtClientReceiveMessage->setTextColor("blue");
            ui->tdtClientReceiveMessage->append("接收消息：" + strMessage);
        }
            break;
        case EM_MESSAGE_SHOW_COLOR_GREEN:
        {
            ui->tdtClientReceiveMessage->setTextColor("green");
            ui->tdtClientReceiveMessage->append("发送消息：" + strMessage);
        }
            break;
    }
}

void CWebsocketTool::ServerOutputMessage(QString strMessage, EM_MESSAGE_SHOW_COLOR emShowColor)
{
    switch ( emShowColor )
    {
        case EM_MESSAGE_SHOW_COLOR_RED:
        {
            ui->tdtServerReceiveMessage->setTextColor("red");
            ui->tdtServerReceiveMessage->append("系统消息：" + strMessage);
        }
            break;
        case EM_MESSAGE_SHOW_COLOR_BLUE:
        {
            ui->tdtServerReceiveMessage->setTextColor("blue");
            ui->tdtServerReceiveMessage->append("接收消息：" + strMessage);
        }
            break;
        case EM_MESSAGE_SHOW_COLOR_GREEN:
        {
            ui->tdtServerReceiveMessage->setTextColor("green");
            ui->tdtServerReceiveMessage->append("发送消息：" + strMessage);
        }
            break;
    }
}

void CWebsocketTool::on_btnClientConnect_clicked()
{
    QString strUrl = ui->ldtServerUrl->text();
    if (NULL != m_pWebSocketClient)
    {
        m_pWebSocketClient->open(QUrl(strUrl));
    }
    ClientOutputMessage("正在连接服务器……", EM_MESSAGE_SHOW_COLOR_RED);
}

void CWebsocketTool::on_btnClientDisconnect_clicked()
{
    if (NULL != m_pWebSocketClient)
    {
        m_pWebSocketClient->close();
    }
}

void CWebsocketTool::on_btnClientSendMessage_clicked()
{
    if ( NULL != m_pWebSocketClient )
    {
        m_pWebSocketClient->sendTextMessage(ui->tdtClientSendMessage->toPlainText());
    }
    QString time = QDateTime::currentDateTime().toString("yyyy.MM.dd hh:mm.zzz ddd");
    ClientOutputMessage( time + " " + ui->tdtClientSendMessage->toPlainText(), EM_MESSAGE_SHOW_COLOR_GREEN );
}

void CWebsocketTool::on_btnOpenServer_clicked()
{
    bool bStatus = m_pWebSocketSrever->listen(QHostAddress(ui->ldtServerIp->text()), ui->ldtServerPort->text().toUInt());
    if ( !bStatus )
    {
        ServerOutputMessage("Server is started failure!", EM_MESSAGE_SHOW_COLOR_RED);
        ServerOutputMessage(QString("Server Error: %1").arg(m_pWebSocketSrever->errorString()), EM_MESSAGE_SHOW_COLOR_RED);
        return;
    }
    ServerOutputMessage("Server is started successfully!", EM_MESSAGE_SHOW_COLOR_RED);
    ui->btnCloseServer->setEnabled(true);
    ui->btnOpenServer->setEnabled(false);
    connect(m_pWebSocketSrever, &QWebSocketServer::newConnection, this, &CWebsocketTool::SlotNewConnection);
}

void CWebsocketTool::on_btnCloseServer_clicked()
{
    if ( NULL != m_pWebSocketSrever )
    {
        m_pWebSocketSrever->close();
    }
    ui->btnCloseServer->setEnabled(false);
    ui->btnOpenServer->setEnabled(true);
    disconnect(m_pWebSocketSrever, &QWebSocketServer::newConnection, this, &CWebsocketTool::SlotNewConnection);
    ServerOutputMessage("Server is stopped!", EM_MESSAGE_SHOW_COLOR_RED);
}

void CWebsocketTool::on_btnServerSend_clicked()
{
    for ( int i = 0; i < m_WebSocketList.count(); i++ )
    {
        m_WebSocketList.at(i)->sendTextMessage(ui->tdtServerSendMessage->toPlainText());
    }
    QString time = QDateTime::currentDateTime().toString("yyyy.MM.dd hh:mm.zzz ddd");
    ServerOutputMessage( time + " " + ui->tdtServerSendMessage->toPlainText(), EM_MESSAGE_SHOW_COLOR_GREEN );
}

void CWebsocketTool::SlotClientConnected()
{
    ClientOutputMessage("服务器连接成功！", EM_MESSAGE_SHOW_COLOR_RED);
    ui->btnClientConnect->setEnabled(false);
    ui->btnClientDisconnect->setEnabled(true);
    ui->labClientStatus->setStyleSheet("color:green;");
    ui->labClientStatus->setText("Connect");
}

void CWebsocketTool::SlotClientDisconnected()
{
    ClientOutputMessage("与服务器断开连接！", EM_MESSAGE_SHOW_COLOR_RED);
    ui->btnClientConnect->setEnabled(true);
    ui->btnClientDisconnect->setEnabled(false);
    ui->labClientStatus->setStyleSheet("color:red;");
    ui->labClientStatus->setText("Disconnect");
}

void CWebsocketTool::SlotClientConnectError(QAbstractSocket::SocketError error)
{
    ClientOutputMessage("客户端连接错误： " + QString(error), EM_MESSAGE_SHOW_COLOR_RED);
    ui->btnClientConnect->setEnabled(true);
    ui->btnClientDisconnect->setEnabled(false);
}

void CWebsocketTool::SlotClientReceiveMessages(QString strMessage)
{
    QString time = QDateTime::currentDateTime().toString("yyyy.MM.dd hh:mm.zzz ddd");
    ClientOutputMessage(time + strMessage , EM_MESSAGE_SHOW_COLOR_BLUE);
}

void CWebsocketTool::SlotNewConnection()
{
    m_pWebSocket = m_pWebSocketSrever->nextPendingConnection();
    ServerOutputMessage(QString("New client connect: %1 %2").arg(m_pWebSocket->origin()).arg(m_pWebSocket->peerAddress().toString()), EM_MESSAGE_SHOW_COLOR_RED);

    m_WebSocketList.append(m_pWebSocket);

    connect(m_pWebSocket, &QWebSocket::disconnected, this, &CWebsocketTool::SlotDisconnection);
    connect(m_pWebSocket, &QWebSocket::textMessageReceived, this, &CWebsocketTool::SlotServerMessageReceived);

    QString strPeerName = m_pWebSocket->requestUrl().toString();

    ui->lwtOnLineClient->addItem(strPeerName);
    m_WebSocketMap.insert(strPeerName, m_pWebSocket);
}

void CWebsocketTool::SlotDisconnection()
{
    QWebSocket *pWebSocketClient = qobject_cast<QWebSocket *>(sender());

    if ( m_WebSocketList.contains(pWebSocketClient) )
    {
        m_WebSocketList.removeOne(pWebSocketClient);
    }
    QList<QListWidgetItem *> list;
    list = ui->lwtOnLineClient->findItems(pWebSocketClient->requestUrl().toString(), Qt::MatchCaseSensitive);

    int r = ui->lwtOnLineClient->row(list.at(0));

    QListWidgetItem *item = ui->lwtOnLineClient->takeItem(r);
    ui->lwtOnLineClient->removeItemWidget(item);
    delete item;

    ServerOutputMessage(QString("Client %2 %1 disconnect").arg(pWebSocketClient->origin()).arg(pWebSocketClient->peerAddress().toString()), EM_MESSAGE_SHOW_COLOR_RED);
    pWebSocketClient->deleteLater();

}

void CWebsocketTool::SlotServerMessageReceived(QString strMessage)
{
    QWebSocket *pWebSocketClient = qobject_cast<QWebSocket *>(sender());
    QString time = QDateTime::currentDateTime().toString("yyyy.MM.dd hh:mm.zzz ddd");
    ServerOutputMessage( time + QString(" %1 ").arg(pWebSocketClient->peerAddress().toString()) + strMessage, EM_MESSAGE_SHOW_COLOR_BLUE );
}
